package Singleton;

/**
 * @Author: 蔡翔
 * @Date: 2019/12/3 15:42
 * @Version 1.0
 */
public class LazyDoubleCheckSingleton {
    //这里加volatile(贡献内存，同步数据) 就可以“防止”cpu指令对LazyDoubleCheckSingleton进行重排序（所有线程都看得到lazyDoubleCheckSingleton 在内存中的状态）
    private volatile static LazyDoubleCheckSingleton lazyDoubleCheckSingleton = null;
    private LazyDoubleCheckSingleton(){

    }
    public static LazyDoubleCheckSingleton getInstance(){
        if(lazyDoubleCheckSingleton == null){
            synchronized (LazyDoubleCheckSingleton.class){
                // 这里再判断了一次 就是doubleCheck
                if(lazyDoubleCheckSingleton == null){
                    //1.分配内存
                    //2.初始化对象
                    //3.设置lazyDoubleCheckSingleton 指向刚分配的内存地址。
                    // ---- 但是cpu重排序可能会使 2,3 反着来 -----
                    // ---- 重排序造成的后果分配好了内存并且指向了lazyDoubleCheckSingleton，但是其他线程并不知道它未初始化对象
                    //       只知道它 非null ，所以就就只拿来用了，就会报空指针异常 -----

                    //1.分配内存
                    //3.设置lazyDoubleCheckSingleton 指向刚分配的内存地址。
                    //2.初始化对象
                    String a = "123";
                    lazyDoubleCheckSingleton = new LazyDoubleCheckSingleton();
                }
            }
        }
        return lazyDoubleCheckSingleton;
    }
}
